// #include "AnimationClipWidget.h"
// #include <SECore/Layer.h>
// #include <SECore/CoreApplication.h>
// #include <SEEdit/Descriptors/SelectActorDescriptor.h>
// #include <SECore/Ecs/Actor.h>
// #include <SEngine/Ecs/Components/AllComponents.h>

// #include <imgui_internal.h>
// #include <ImSequencer.h>
// #include <ImCurveEdit.h>


// namespace SEngine
// {
//     struct RampEdit : public ImCurveEdit::Delegate
//     {
//         RampEdit()
//         {
//             // mPts[0][0] = ImVec2(-10.f, 0);
//             // mPts[0][1] = ImVec2(20.f, 0.6f);
//             // mPts[0][2] = ImVec2(25.f, 0.2f);
//             // mPts[0][3] = ImVec2(70.f, 0.4f);
//             // mPts[0][4] = ImVec2(120.f, 1.f);
//             mPointCount[0] = 0;
    
//             // mPts[1][0] = ImVec2(-50.f, 0.2f);
//             // mPts[1][1] = ImVec2(33.f, 0.7f);
//             // mPts[1][2] = ImVec2(80.f, 0.2f);
//             // mPts[1][3] = ImVec2(82.f, 0.8f);
//             mPointCount[1] = 0;
    
//             // mPts[2][0] = ImVec2(40.f, 0);
//             // mPts[2][1] = ImVec2(60.f, 0.1f);
//             // mPts[2][2] = ImVec2(90.f, 0.82f);
//             // mPts[2][3] = ImVec2(150.f, 0.24f);
//             // mPts[2][4] = ImVec2(200.f, 0.34f);
//             // mPts[2][5] = ImVec2(250.f, 0.12f);
//             mPointCount[2] = 0;
//             mbVisible[0] = mbVisible[1] = mbVisible[2] = true;
//             mMax = ImVec2(1.f, 1.f);
//             mMin = ImVec2(0.f, 0.f);
//         }
//         size_t GetCurveCount() { return 3; }
//         bool IsVisible(size_t curveIndex) { return mbVisible[curveIndex]; }
//         size_t GetPointCount(size_t curveIndex) { return mPointCount[curveIndex]; }
//         uint32_t GetCurveColor(size_t curveIndex) {
//             uint32_t cols[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000};
//             return cols[curveIndex];
//         }
//         ImVec2 *GetPoints(size_t curveIndex) { return mPts[curveIndex]; }
//         virtual ImCurveEdit::CurveType GetCurveType(size_t curveIndex) const { return ImCurveEdit::CurveSmooth; }
//         virtual int EditPoint(size_t curveIndex, int pointIndex, ImVec2 value) {
//             mPts[curveIndex][pointIndex] = ImVec2(value.x, value.y);
//             SortValues(curveIndex);
//             for (size_t i = 0; i < GetPointCount(curveIndex); i++)
//             {
//                 if (mPts[curveIndex][i].x == value.x)
//                     return i;
//             }
//             return pointIndex;
//         }
//         virtual void AddPoint(size_t curveIndex, ImVec2 value) {
//             if (mPointCount[curveIndex] >= 8)
//                 return;
//             mPts[curveIndex][mPointCount[curveIndex]++] = value;
//             SortValues(curveIndex);
//         }
//         virtual ImVec2 &GetMax() { return mMax; }
//         virtual ImVec2 &GetMin() { return mMin; }
//         virtual unsigned int GetBackgroundColor() { return 0; }

//         ImVec2 mPts[3][8];
//         size_t mPointCount[3];
//         bool mbVisible[3];
//         ImVec2 mMin;
//         ImVec2 mMax;
    
//     private:
//         void SortValues(size_t curveIndex) {
//             auto b = std::begin(mPts[curveIndex]);
//             auto e = std::begin(mPts[curveIndex]) + GetPointCount(curveIndex);
//             std::sort(b, e, [](ImVec2 a, ImVec2 b)
//                       { return a.x < b.x; });
//         }
//     };

//     class AnimSequence : public ImSequencer::SequenceInterface
//     {
//     public:
//         struct AnimSequenceItem {
//             std::string mName;
//             int mFrameStart, mFrameEnd;
//             bool mExpanded;
//         };
//     public:
//         AnimSequence() : mFrameMin(0), mFrameMax(0) {}
//         void SetFrameRange(int min, int max) { mFrameMin = min; mFrameMax = max; }
//         void AddItem(AnimSequenceItem item) { myItems.emplace_back(item); }
//         bool HasItem() { return !myItems.empty(); }
//         virtual int GetFrameMin() const { return mFrameMin; }
//         virtual int GetFrameMax() const { return mFrameMax; }
//         virtual int GetItemCount() const { return (int)myItems.size(); }
//         // virtual int GetItemTypeCount() const { return sizeof(SequencerItemTypeNames) / sizeof(char *); }
//         // virtual const char *GetItemTypeName(int typeIndex) const { return SequencerItemTypeNames[typeIndex]; }
//         virtual const char *GetItemLabel(int index) const {
//             static char tmps[512];
//             sprintf_s(tmps, "[%02d] %s", index, myItems[index].mName.c_str());
//             return tmps;
//         }
//         virtual void Get(int index, int **start, int **end, int *type, unsigned int *color) {
//             AnimSequenceItem &item = myItems[index];
//             if (color)
//                 *color = 0xFFAA8080; // same color for everyone, return color based on type
//             if (start)
//                 *start = &item.mFrameStart;
//             if (end)
//                 *end = &item.mFrameEnd;
//             // if (type)
//             //     *type = item.mType;
//         }
//         // virtual void Add(int type) { myItems.push_back(AnimSequenceItem{type, 0, 10, false}); };
//         virtual void Del(int index) { myItems.erase(myItems.begin() + index); }
//         // virtual void Duplicate(int index) { myItems.push_back(myItems[index]); }
//         virtual size_t GetCustomHeight(int index) { return myItems[index].mExpanded ? 300 : 0; }
//         virtual void DoubleClick(int index)
//         {
//             if (myItems[index].mExpanded) {
//                 myItems[index].mExpanded = false;
//                 return;
//             }
//             for (auto &item : myItems)
//                 item.mExpanded = false;
//             myItems[index].mExpanded = !myItems[index].mExpanded;
//         }
//         virtual void CustomDraw(int index, ImDrawList *draw_list, const ImRect &rc, const ImRect &legendRect, const ImRect &clippingRect, const ImRect &legendClippingRect)
//         {
//             static const char *labels[] = {"Translation", "Rotation", "Scale"};

//             rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
//             rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
//             draw_list->PushClipRect(legendClippingRect.Min, legendClippingRect.Max, true);
//             for (int i = 0; i < 3; i++)
//             {
//                 ImVec2 pta(legendRect.Min.x + 30, legendRect.Min.y + i * 14.f);
//                 ImVec2 ptb(legendRect.Max.x, legendRect.Min.y + (i + 1) * 14.f);
//                 draw_list->AddText(pta, rampEdit.mbVisible[i] ? 0xFFFFFFFF : 0x80FFFFFF, labels[i]);
//                 if (ImRect(pta, ptb).Contains(ImGui::GetMousePos()) && ImGui::IsMouseClicked(0))
//                     rampEdit.mbVisible[i] = !rampEdit.mbVisible[i];
//             }
//             draw_list->PopClipRect();

//             ImGui::SetCursorScreenPos(rc.Min);
//             ImCurveEdit::Edit(rampEdit, ImVec2{rc.Max.x - rc.Min.x, rc.Max.y - rc.Min.y}, 137 + index, &clippingRect);
//         }
//         virtual void CustomDrawCompact(int index, ImDrawList *draw_list, const ImRect &rc, const ImRect &clippingRect)
//         {
//             rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
//             rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
//             draw_list->PushClipRect(clippingRect.Min, clippingRect.Max, true);
//             for (int i = 0; i < 3; i++)
//             {
//                 for (int j = 0; j < rampEdit.mPointCount[i]; j++)
//                 {
//                     float p = rampEdit.mPts[i][j].x;
//                     if (p < myItems[index].mFrameStart || p > myItems[index].mFrameEnd)
//                         continue;
//                     float r = (p - mFrameMin) / float(mFrameMax - mFrameMin);
//                     float x = ImLerp(rc.Min.x, rc.Max.x, r);
//                     draw_list->AddLine(ImVec2(x, rc.Min.y + 6), ImVec2(x, rc.Max.y - 4), 0xAA000000, 4.f);
//                 }
//             }
//             draw_list->PopClipRect();
//         }
        
//     private:
//         int mFrameMin, mFrameMax;
//         std::vector<AnimSequenceItem> myItems;
//         RampEdit rampEdit;
//     };
  
//     AnimationClipWidget::AnimationClipWidget(EditLayer & layer)
//         : Widget(), m_layer(layer)
//     {
//     }

//     void AnimationClipWidget::BeginUpdate() {

//     }

//     void AnimationClipWidget::UpdateImpl(int delta) {
//         auto selectActor = m_layer.GetApp().GetDescriptor<SelectActorDescriptor>()->get();
//         if (selectActor.selectActor && selectActor.selectActor->get().HasComponent<AnimationComp>()) {
//             auto & animComp = selectActor.selectActor->get().GetComponent<AnimationComp>()->get();
//             static AnimSequence animSequence;
//             static int frameMin = 0;
//             static int frameMax = 100;
//             static int currentFrame = 0;
//             static bool expanded = true;
//             static int selectedEntry = 0;
//             static int firstFrame = 0;

//             ImGui::Columns(3, 0, false);
//             ImGui::SetColumnWidth(0, 230);
//             ImGui::SetColumnWidth(1, 230);
//             ImGui::SetColumnWidth(2, 230);
//             ImGui::InputInt("Frame Min", &frameMin); ImGui::NextColumn();
//             ImGui::InputInt("Frame", &currentFrame); ImGui::NextColumn();
//             ImGui::InputInt("Frame Max", &frameMax); ImGui::NextColumn();
//             ImGui::Columns();

//             ImGui::Button("Add key"); ImGui::SameLine();
//             ImGui::Button("Remove key");

//             animSequence.SetFrameRange(frameMin, frameMax);
//             Sequencer(&animSequence, &currentFrame, &expanded, &selectedEntry, &firstFrame, ImSequencer::SEQUENCER_EDIT_ALL | ImSequencer::SEQUENCER_DEL);
            
//             if (ImGui::BeginPopupContextWindow("AnimationMenu")) {
//                 for (auto & [compName, compProp] : animComp.m_properties) {
//                     if (ImGui::BeginMenu(compName.c_str())) {
//                         for (auto & [compPropName, param] : compProp) {
//                             if (ImGui::MenuItem(compPropName.c_str())) {
//                                 animSequence.AddItem(AnimSequence::AnimSequenceItem{compPropName, 0, 50, false});
//                             }
//                         }
//                         ImGui::EndMenu();
//                     }
//                 }
//                 ImGui::EndPopup();
//             }
//         }
//     }

//     void AnimationClipWidget::EndUpdate() {

//     }

// }